/**
 *  RootSet.java        22-ott-2009
 *   
 * Copyright (c) 2009 mentalsmash.org
 *  
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * 
 *  The use of the Apache License does not indicate that this project is
 *  affiliated with the Apache Software Foundation.
 */

package org.mentalsmash.tazio.transactions;

import java.io.Serializable;
import java.util.Iterator;
import org.mentalsmash.tazio.transactions.management.TransactionStateException;
import org.mentalsmash.tazio.transactions.objects.TransactionalObject;

/**
 * The <tt>Share</tt> is the interface for user on a WRM to access to
 * Transacitonal Objects
 * 
 * @author Andrea Reale
 * 
 */
public interface Share extends Iterable<Serializable> {

    /**
     * Instantiates a TransactionalObject of the type given as parameter
     * <code>objectType</code>. That transactional object is automatically added
     * to the share.
     * <p>
     * <strong>NOTE:</strong> For the initial prototypical implementation this
     * method can be called only if the current thread does not already own an
     * active transactions. <br />
     * That is because it needs to start a separate transaction to modify the
     * <tt>RootSet</tt>, to avoid possible conflicts with other operations in
     * the context of the same transaction.
     * </p>
     * 
     * @param objectType
     *            The class of the object to be instantiated. This class has to
     *            respect the conventions for {@link TransactionalObjects} and
     *            implement the {@link Serializable} interface
     * @param mnemonic
     *            a set of properties that can be used to identify the object
     *            inside the share. If an object having the same set of
     *            properties does already exist, an Exception shoud be thrown
     * @return
     * @throws TransactionStateException
     *             if a transaction is already associated to the current thread
     * @throws RollbackException
     *             if the modification to the root set is rejected
     */
    <T extends Serializable> T createObject(Class<T> objectType,
	    String propertiesString) throws TransactionStateException,
	    RollbackException;

    /**
     * Remove an object from the RootSet.
     * <p>
     * The object must be an instance that was created by using this instance of
     * <tt>RootSet</tt> and must therefore be in the <tt>RootSet</tt>
     * </p>
     * <p>
     * <strong>NOTE:</strong> For the initial prototypical implementation this
     * method can be called only if the current thread does not already own an
     * active transactions. <br />
     * That is because it needs to start a separate transaction to modify the
     * <tt>RootSet</tt>, to avoid possible conflicts with other operations in
     * the context of the same transaction.
     * </p>
     * 
     * @param toRemove
     *            The opaque instance of the {@link TransactionalObject} to
     *            remove.
     * @return
     * @throws TransactionStateException
     *             if a transaction is already associated to the current thread
     * @throws RollbackException
     *             if the modification to the root set is rejected
     */
    boolean removeObject(Object toRemove) throws TransactionStateException,
	    RollbackException;

    /**
     * Retrieves an object from the root set, given its mnemonic id
     * 
     * @param objProperties
     *            A set of properties specifieng the object to be returned. Those properties must be exactly
     *            the same as the properties used to register the object.
     * @return the object in the rootset, or <code>null</code> if no such object
     */
    <T extends Serializable> T getObject(String propertiesString);

    /**
     * Gets an immutable iterator over the <tt>RootSet</tt>
     * 
     * @return an immutable iterator over the <tt>RootSet</tt>
     */
    Iterator<Serializable> iterator();

}
